RISC

您所在的位置:网站首页 寄存器MLPS Regfile电路 RISC

RISC

2024-07-10 06:11| 来源: 网络整理| 查看: 265

一、寄存器堆介绍

对于RISC-V基础指令集中共包含32个通用寄存器(x0~x31)。寄存器堆可以说是整个cpu的核心,我们可以回想RISC-V指令集,几乎所有类型的指令都要与寄存器打交道的(个人理解)。

注意:x0默认为0x00000000,是一个只读寄存器。

二、寄存器堆功能

上图是一个寄存器module,我可以如果先不思考寄存器内部如何实现,只是把寄存器堆想成一个黑匣子,我们可以思考它到底要干什么那?

我个人理解,寄存器堆实际上就是在系统时钟的控制下,从寄存器堆中对于位置读取数据,或者向对应位置写入数据。如果这样理解的话我们就可以思考出一个寄存器堆都需要什么信号了。

1.系统时钟,复位信号(这个相信大家都理解)

2.读写地址信号。既然要向寄存器堆中读写数据,而一个寄存器堆共有32个寄存器,怎么确定要读写那个寄存器呀?事实上每个寄存器在寄存器堆中都有对应的地址,我们只需要给出地址,就可以找到对应地址。(为啥为5位地址:32个寄存器,如果要表示就要用5位二进制数来表示)

3.读写数据信号。如果上面这个地址信号理解了,那么寄存器堆已经知道了要读写的地址,那么这个地址到底要写入啥,或者读出了什么,则一定需要有信号表示读出的数据或者写入的数据。

4.是否写信号。如果对RISC-V指令系统了解的清楚的话,我们就知道有些类型数指令需要向寄存器堆中写入数据(如:I型 R型),而有些类型指令则不需要向寄存器堆中写入数据(如:S型)。因此一定需要一个信号来高速寄存器堆是否读写。

具体如下:

 可以看到输入信号有:时钟,复位,rs1,rs2,rd,wen,busw

而输出信号则是:从对应寄存器中读出的数据:BusA,BusB。

三、verilog代码实现

module RegFile( input clk, input rstn, input [4:0]Rs1, //第一个寄存器地址 input [4:0]Rs2, //第二个寄存器地址 input [4:0]Rd, //写入的寄存器地址 input Wen, //控制信号 output [31:0]BusA, //输出第一个寄存器中的值 output [31:0]BusB, //输出第二个寄存器中的值 input [31:0]BusW //写个的寄存器的值 ); reg [31:0]DataReg[31:0]; //定义出来这个寄存器 reg [31:0]BusA1,BusB1; //输出的中间变量 reg [31:0]Waddr; always@(Rd)begin case(Rd) 5'b00000 : Waddr=32'h0000_0001; 5'b00001 : Waddr=32'h0000_0002; 5'b00010 : Waddr=32'h0000_0004; 5'b00011 : Waddr=32'h0000_0008; 5'b00100 : Waddr=32'h0000_0010; 5'b00101 : Waddr=32'h0000_0020; 5'b00110 : Waddr=32'h0000_0040; 5'b00111 : Waddr=32'h0000_0080; 5'b01000 : Waddr=32'h0000_0100; 5'b01001 : Waddr=32'h0000_0200; 5'b01010 : Waddr=32'h0000_0400; 5'b01011 : Waddr=32'h0000_0800; 5'b01100 : Waddr=32'h0000_1000; 5'b01101 : Waddr=32'h0000_2000; 5'b01110 : Waddr=32'h0000_4000; 5'b01111 : Waddr=32'h0000_8000; 5'b10000 : Waddr=32'h0001_0000; 5'b10001 :Waddr=32'h0002_0000; 5'b10010 : Waddr=32'h0004_0000; 5'b10011 : Waddr=32'h0008_0000; 5'b10100 : Waddr=32'h0010_0000; 5'b10101 : Waddr=32'h0020_0000; 5'b10110 : Waddr=32'h0040_0000; 5'b10111 : Waddr=32'h0080_0000; 5'b11000 : Waddr=32'h0100_0000; 5'b11001 : Waddr=32'h0200_0000; 5'b11010 : Waddr=32'h0400_0000; 5'b11011 : Waddr=32'h0800_0000; 5'b11100 : Waddr=32'h1000_0000; 5'b11101 : Waddr=32'h2000_0000; 5'b11110 : Waddr=32'h4000_0000; 5'b11111 : Waddr=32'h8000_0000; endcase end wire [31:0] W_en; assign W_en=Waddr&{32{Wen}}; //向第1个寄存器写入 always@(posedge clk or negedge rstn) if(!rstn) DataReg[0]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3